package cc.yihy.storage.qiniu.bean;

import cc.yihy.storage.StorageClient;
import cc.yihy.storage.entity.UpResult;
import cc.yihy.storage.util.StorageUtil;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author Yihy
 * @version V1.0
 * @Package cc.yihy.storage
 * @Description:
 * @date 2017/6/27 15:50
 */
public class SimpleQiniuClient implements StorageClient {

    private final static Logger log = LoggerFactory.getLogger(SimpleQiniuClient.class);
    private Auth auth;
    private String bucketName;
    private String domain;

    private UploadManager uploadManager;
    private BucketManager bucketManager;

    public SimpleQiniuClient(Auth auth, String bucketName) {
        this.auth = auth;
        this.bucketName = bucketName;
    }

    //简单上传，使用默认策略，只需要设置上传的空间名就可以了
    private String getUpToken() {
        StringMap putPolicy = new StringMap();
        putPolicy.put("returnBody", "{\"fileName\":\"$(key)\",\"unique\":\"$(etag)\",\"fileSize\":$(fsize)}");
        putPolicy.put("callbackBodyType", "application/json");
        long expireSeconds = 3600;

        return auth.uploadToken(bucketName, null, expireSeconds, putPolicy);
    }

    public UpResult upload(InputStream inputStream, String fileName) {
        UpResult result = new UpResult();
        try {
            //调用put方法上传application/octet-stream
            Response res = uploadManager.put(inputStream, fileName, getUpToken(), null, null);

            log.info(res.bodyString());

            if (res.isOK()) {
                result = res.jsonToObject(UpResult.class);
            }
        } catch (QiniuException e) {
            Response r = e.response;

            log.warn("upload storage to Qiniu failed", e);
            // 请求失败时打印的异常的信息
//            System.out.println(r.toString());
            try {
                //响应的文本信息
                log.warn(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
        }
        return result;

    }

    //普通上传
    public UpResult upload(String filePath, String fileName) throws IOException {
        UpResult result = new UpResult();
        try {
            //调用put方法上传
            Response res = uploadManager.put(filePath, fileName, getUpToken());

            log.info(res.bodyString());

            if (res.isOK()) {
                result = res.jsonToObject(UpResult.class);
            }
        } catch (QiniuException e) {
            Response r = e.response;

            log.warn("upload storage to Qiniu failed", e);
            // 请求失败时打印的异常的信息
//            System.out.println(r.toString());
            try {
                //响应的文本信息
                log.warn(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
        }
        return result;
    }

    public String getDomain() {
        return domain;
    }

    public String getImageUrl(String fileName) {
        return StorageUtil.filePath(domain,fileName);
    }

    @Override
    public boolean delete(String fileKey) {


        try {
            bucketManager.delete(bucketName, fileKey);
            return true;
        } catch (QiniuException ex) {
            //如果遇到异常，说明删除失败
            System.err.println(ex.code());
            System.err.println(ex.response.toString());
        }
        return false;
    }

    public void setAuth(Auth auth) {
        this.auth = auth;
    }

    public UploadManager getUploadManager() {
        return uploadManager;
    }

    public void setUploadManager(UploadManager uploadManager) {
        this.uploadManager = uploadManager;
    }

    public BucketManager getBucketManager() {
        return bucketManager;
    }

    public void setBucketManager(BucketManager bucketManager) {
        this.bucketManager = bucketManager;
    }

    public String getBucketName() {
        return bucketName;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }
}
